use std::ops::Deref;
use std::sync::Arc;
use serde::{Deserialize, Serialize};
use sqlx::{Pool, QueryBuilder, Row, Sqlite};
use sqlx::sqlite::SqliteRow;
use crate::models::bili::tag::BiliPictureTagModel;

pub static BILI_PICTURE_DDL: &str = r#"
create table if not exists "bili_picture"
(
    img_src    text not null
        constraint bili_album_picture_pk
            primary key,
    img_width  integer,
    img_height integer,
    img_size   integer,
    deleted    integer
);
"#;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BiliPictureModel {
    pub img_src: String,
    pub img_width: i64,
    pub img_height: i64,
    pub img_size: f64,
    pub img_tags: Option<Vec<BiliPictureTagModel>>,
    pub deleted: bool,
}

// impl TryFrom<SqliteRow> for BiliPictureModel {
//     type Error = anyhow::Error;
//
//     fn try_from(row: SqliteRow) -> Result<Self, Self::Error> { Self::try_from(&row) }
// }

// impl TryFrom<&SqliteRow> for BiliPictureModel {
//     type Error = anyhow::Error;
//
//     fn try_from(row: &SqliteRow) -> Result<Self, Self::Error> {
//         let img_src: String = row.try_get("img_src")?;
//         Ok(Self {
//             img_src: img_src.clone(),
//             img_width: row.try_get("img_width")?,
//             img_height: row.try_get("img_height")?,
//             img_size: row.try_get("img_size")?,
//             img_tags: async_std::task::block_on(async {
//                 let tags = BiliPictureTagModel::select_all("img_src", &img_src).await;
//                 if tags.is_empty() { None }
//                 else { Some(tags) }
//             }),
//             deleted: row.try_get("deleted")?,
//         })
//     }
// }

// impl BiliPictureModel {
//     pub async fn select_all(include_deleted: bool) -> Vec<Self> {
//         let db = Arc::clone(&DATA_DB);
//         let mut qb: QueryBuilder<Sqlite> = QueryBuilder::new("select * from bili_picture");
//         if !include_deleted {
//             qb.push(" where deleted=");
//             qb.push_bind(0);
//         }
//         let query = qb.build();
//         let db = db.lock().await;
//         let queryset = query.fetch_all(db.deref())
//             .await
//             .unwrap();
//         queryset.into_iter()
//             .filter_map(|x| Self::try_from(x).ok())
//             .collect::<Vec<Self>>()
//     }
// }